package com.portal.base.security.token;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.Verification;
import com.google.common.base.Joiner;
import com.portal.base.core.constant.DataBaseConstant;
import com.portal.base.core.exception.JeecgBootException;
import com.portal.base.core.util.SpringContextUtils;
import com.portal.base.core.util.oConvertUtils;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author Scott
 * @Date 2018-07-12 14:23
 * @Desc JWT工具类
 **/
public class JwtUtil {

    // Token过期时间30分钟（用户登录过期时间是此时间的两倍，以token在reids缓存时间为准）
    public static final long EXPIRE_TIME = 30 * 60 * 1000;

    /**
     * 校验token是否正确
     *
     * @param token  密钥
     * @param para 验证的参数map
     * @param secret hash标准
     * @return 是否正确
     */
    public static boolean verify(String token, HashMap<String,String> para, String secret) {
        try {
            // 根据密码生成JWT效验器
            Algorithm algorithm = Algorithm.HMAC256(secret);
            //JWTVerifier verifier = JWT.require(algorithm).withClaim(key, value).build();
            Verification verification = JWT.require(algorithm);
            /*for (Map.Entry<String,String> entry : para.entrySet()){

                verification.withClaim(entry.getKey(),entry.getValue());
            }*/
            para.forEach((k,v)->verification.withClaim(k,v));
            JWTVerifier verifier = verification.build();
            // 效验TOKEN
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public static String getParaByKey(String token,String key) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim(key).asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 生成签名,5min后过期
     *
     * @param para token的附加信息
     * @param secret   hash的标准
     * @return 加密的token
     */
    public static String sign(HashMap<String,String> para, String secret) {
        Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
        Algorithm algorithm = Algorithm.HMAC256(secret);
        JWTCreator.Builder builder =JWT.create();
        para.forEach((k,v)->builder.withClaim(k,v));
        // 附带username信息
        return builder.withExpiresAt(date).sign(algorithm);

    }

    /**
     * 根据request中的token获取用户账号
     *
     * @param request
     * @return
     * @throws JeecgBootException
     */
    public static String getUserNameByToken(HttpServletRequest request,String key) throws JeecgBootException {
        String accessToken = request.getHeader("X-Access-Token");
        String username = getParaByKey(accessToken,key);
        if (oConvertUtils.isEmpty(username)) {
            throw new JeecgBootException("未获取到用户");
        }
        return username;
    }

    /**
     * 从session中获取变量
     *
     * @param key
     * @return
     */
    public static String getSessionData(String key) {
        //${myVar}%
        //得到${} 后面的值
        String moshi = "";
        if (key.indexOf("}") != -1) {
            moshi = key.substring(key.indexOf("}") + 1);
        }
        String returnValue = null;
        if (key.contains("#{")) {
            key = key.substring(2, key.indexOf("}"));
        }
        if (oConvertUtils.isNotEmpty(key)) {
            HttpSession session = SpringContextUtils.getHttpServletRequest().getSession();
            returnValue = (String) session.getAttribute(key);
        }
        //结果加上${} 后面的值
        if (returnValue != null) {
            returnValue = returnValue + moshi;
        }
        return returnValue;
    }



    public static void main(String[] args) {
        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1ODk0NjM5NTYsInVzZXJuYW1lIjoiYWRtaW4ifQ.M053jZQ-GcO5T1wQKizTwELgGl5hhwtuVJrjarQhnpc";
        System.out.println(JwtUtil.getParaByKey(token,"username"));
        HashMap<String,String> para = new HashMap<String,String>();
        para.put("username","xuduo");
        para.put("age","25");
        String secret = "123";
        String token2 = sign(para,secret);
        System.out.println("token2:"+token2);
        System.out.println(verify(token2,para,secret));
        System.out.println(getParaByKey(token2,"username"));
        System.out.println(getParaByKey(token2,"age"));
    }
}
